    //
//  TGMModel2TableViewAdapter.m
//  TravelGuideMdd
//
//  Created by Song Xiaofeng on 13-9-11.
//  Copyright (c) 2013年 mafengwo.com. All rights reserved.
//

#import "TGMModel2TableViewAdapter.h"

#define RefreshHeaderViewTag    1111

#define DefaultEmptyCellHeight 200

@interface TGMModel2TableViewAdapter()<UITableViewDataSource, UITableViewDelegate>
{
//    BOOL _refreshError;
}

@end
@implementation TGMModel2TableViewAdapter

- (id)init
{
    self = [super init];
    if (self)
    {
        _initOffsetY = OFFSETY_UNKNOW;
        _refreshLoading = NO;
        _refreshError   = NO;
        _hasBinded = NO;
        _emptyCellReceiveClick = YES;
        _emptyCellHeight = 0;
        _getMoreCell = [[TGMTableMoreCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TGMTableMoreCell"];
        _emptyCell  = [[TGMTableEmptyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TGMTableEmptyCell"];
        @weakify(self);
        _emptyCell.refreshActionBlock = ^{
            if (weak_self.emptyCellErrorViewClickRefreshBlock){
                weak_self.emptyCellErrorViewClickRefreshBlock();
            }
        };
        _emptyCell.openSettingBlock = ^{
            if (weak_self.emptyCellErrorViewClickOpenSetting){
                weak_self.emptyCellErrorViewClickOpenSetting();
            }
        };
//        默认图在emptyCell设置
//        if (IS_IPAD)
//        {
//            self.emptyContentImage = [UIImage imageNamed:@"img_nodownload"];
//        }
//        else
//        {
//            self.emptyContentImage = [UIImage imageNamed:@"re_load"];
//        }
    
    }
    return self;
}

-(void)setShowErrorViewWhenNotNet:(BOOL)showErrorViewWhenNotNet{
    _emptyCell.showErrorViewWhenNotNetWork = showErrorViewWhenNotNet;
}

- (void)buildListData
{
    self.listData = [_model listModelItemForDataId:self.actionData.dataId];
}


- (BOOL)hasBinded
{
    return _tableView && _hasBinded;
}


- (void)bindTableView:(UITableView *)tableview
            withModel:(TGMBaseModel *)model
           actionData:(TGMBaseModelActionData *)data
            atOffsetY:(int)initOffsetY
{
    NSAssert([NSThread isMainThread], @"MUST BIND IN MAIN THREAD!!!");
    _hasBinded = YES;
    _tableView = tableview;
    _scrollView = tableview;
    _model = model;
    _actionData = data;
    _initOffsetY = initOffsetY;
    [[model class] addDataObserver:self];
    
    UIView *headerView = [_tableView viewWithTag:RefreshHeaderViewTag];
    if (headerView)
    {
        [headerView removeFromSuperview];
    }
    
    [self buildListData];
    
    _tableView.delegate = self;
    _tableView.dataSource = self;
    _tableView.contentInset = [self contextScrollViewContentInset];
    
    [self cleanPullToRefreshFacadeStyle];
    if ([self supportPullRefreshHeader])
    {
        [self requirePullToRefreshFacadeStyle];
    }
    
    if (initOffsetY == OFFSETY_UNKNOW )
    {
        if ([self shouldModelInitRefresh])
        {
            _refreshLoading = YES;
            [self triggerModelInitRefresh];
        }
        else
        {
            UIEdgeInsets inset = [self contextScrollViewContentInset];
            [_tableView setContentOffset:CGPointMake(0, -inset.top) animated:NO];
            [_tableView reloadData];
        }
    }
    else
    {
        CGPoint contentOffset = CGPointMake(0, initOffsetY);
        [_tableView reloadData];
        [_tableView setContentOffset:contentOffset animated:NO];
    }
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(hasCacheWithAdapter:)])
    {
        [self.delegate hasCacheWithAdapter:self];
    }
}

- (void)triggerModelInitRefresh
{
    [self triggerRefresh];
}

- (void)bindTableView:(UITableView*)tableview
            withModel:(TGMBaseModel*)model
           actionData:(TGMBaseModelActionData*)data
            atOffsetY:(int)initOffsetY
           emptyImage:(UIImage*)emptyImage
            emptyText:(NSString*)emptyText
{
    self.emptyContentImage = emptyImage;
    self.emptyContentText = emptyText;
    [self bindTableView:tableview withModel:model actionData:data atOffsetY:initOffsetY];
}

- (int)markedContentOffsetYOfTableView;
{
    if (_refreshLoading)
    {
        return OFFSETY_UNKNOW;
    }
    else
    {
        return _tableView.contentOffset.y;
    }
}

- (BOOL)isRefreshLoading
{
    return _refreshLoading && self.currentOperationTask && self.currentOperationTask.dataRequestType == kMFWDataRequest_Refresh;
}

- (void)dealloc
{
    if (_tableView.delegate == self)
    {
        _tableView.delegate = nil;
    }
    if (_tableView.dataSource == self)
    {
        _tableView.dataSource = nil;
    }

    [[_model class] removeDataObserver:self];
    if (self.currentOperationTask)
    {
        [self.currentOperationTask cancel];
        self.currentOperationTask = nil;
    }
}

- (void)requestRefresh
{
    [super requestRefresh];
    
    if (self.currentOperationTask)
    {
        _emptyCell.state = EmptyCellState_Loading;
    }
    
    [_tableView reloadData];
}

- (void)requestRefreshWithNonAnimation{
    [super requestRefresh];
}

- (void)requestGetMore
{
    [super requestGetMore];
    
    if (self.currentOperationTask)
    {
        [_getMoreCell setInfoText:@"正在加载更多..." forState:MoreCellState_Loading];
    }
}

- (void)reloadUIData:(BOOL)refreshed byRequestType:(MFWDataRequestType)type
{
    if (type == kMFWDataRequest_Refresh)
    {
        if (refreshed)
        {
            [self buildListData];
            [_tableView reloadData];
        }
        else
        {
            [_tableView reloadData];
        }
    }
    else if (type == kMFWDataREquest_GetMore)
    {
        if (refreshed)
        {
            [_getMoreCell setInfoText:@"查看更多" forState:MoreCellState_Information];
            [_tableView reloadData];
        }
        else
        {
            [_getMoreCell setInfoText:@"加载更多失败，点击查看更多" forState:MoreCellState_Information];
        }
    }
    if(self.delegate != nil && [self.delegate respondsToSelector:@selector(onReloadData:)]) {
        [self.delegate onReloadData:self];
    }
}

- (MFWTask*)startRefreshRequest
{
    TGMBaseModelActionData *actionData = [self actionDataForRequestModelData:kMFWDataRequest_Refresh];
    _actionData = actionData;
    return [self.model requestRefresh:actionData];
}

- (MFWTask*)startGetMoreRequest
{
    TGMBaseModelActionData *actionData = [self actionDataForRequestModelData:kMFWDataREquest_GetMore];
    return [self.model requestGetMore:actionData];
}

- (BOOL)supportPullRefreshHeader
{
    return NO;
}

- (BOOL)supportGetMoreFooter
{
    return NO;
}

- (BOOL)shouldModelInitRefresh;//default return YES
{
    return [self.model needRefreshForDataId:_actionData.dataId];
}

- (BOOL)hasMoreData;
{
    return [self.model canGetMoreForDataId:_actionData.dataId];
}

#pragma mark - UITableViewDataSource & UITableViewDelegate

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    NSArray *listData = self.listData;
    NSInteger count = [listData count];
    if (count == 0) {
        return 1;
    }
    
    return [self model2UITableView_numberOfSectionsInTableView:tableView];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
    NSArray *listData = self.listData;
    NSInteger count = [listData count];
    
    if (count == 0 && section == 0)
    {
        if (_refreshLoading)
        {
            if (![self supportPullRefreshHeader])
            {
                count++;
            }
            
        }
        else if (!_refreshLoading)
        {
            count ++;
        }
    }
    else
    {
        count = [self model2UITableView: tableView numberOfRowsInSection: section];
        
        if ([self supportGetMoreFooter]
            && section == [tableView numberOfSections]-1)
        {
            if ([self hasMoreData]) {
                count++;
            } else {
                CGFloat noMoreDataHeight = [self model2UITableView_heightForNoMoreDataCell:self.tableView];
                if (noMoreDataHeight > 0) {
                    count++;
                }
            }
        }
    }
    return count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    NSInteger count = [self.listData count];
    if (count == 0 && indexPath.section == 0 && indexPath.row == 0)
    {
        if (_refreshLoading)
        {
            if (![self supportPullRefreshHeader])
            {
                _emptyCell.state = EmptyCellState_Loading;
                return _emptyCell;
            }
        }
        else if (!_refreshLoading)
        {
            if (_refreshError)
            {
                _emptyCell.state = EmptyCellState_Error;
            }
            else
            {
                if (_emptyCell.emptyImage == nil)
                {
                    _emptyCell.emptyImage = self.emptyContentImage;
                }
                if (self.emptyCellActionString != nil && self.emptyCellActionString.length != 0){
                    _emptyCell.actionString = self.emptyCellActionString;
                }
                if (self.emptyCellUrl != nil && self.emptyCellUrl.length != 0)
                {
                    _emptyCell.jumpUrl = self.emptyCellUrl;
                }
                _emptyCell.state = EmptyCellState_Tips;

                if (self.emptyContentText != nil && self.emptyContentText.length != 0)
                {
                    _emptyCell.emptyText = self.emptyContentText;
                }
                _emptyCell.state = EmptyCellState_Tips;
            }
            return _emptyCell;
        }
    }
    else if (count > 0
             && [self supportGetMoreFooter]
             && indexPath.section == [tableView numberOfSections]-1
             && indexPath.row == [tableView numberOfRowsInSection:indexPath.section]-1)
    {
        if ([self hasMoreData]) {
            if (self.currentOperationTask && self.currentOperationTask.dataRequestType == kMFWDataREquest_GetMore)
            {
                //            [_getMoreCell setInfoText:@"" forState:MoreCellState_Loading];
            }
            else
            {
                [_getMoreCell setInfoText:@"查看更多" forState:MoreCellState_Information];
            }
            return _getMoreCell;
        } else {
            CGFloat noMoreDataHeight = [self model2UITableView_heightForNoMoreDataCell:self.tableView];
            if (noMoreDataHeight > 0) {
                return _noMoreDataCell;
            }
        }
    }
    
    return [self model2UITableView:tableView cellForRowAtIndexPath:indexPath];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    NSArray *listData = self.listData;
    NSInteger count = [listData count];
    
    if (count == 0 && indexPath.section == 0 && indexPath.row == 0)
    {
        NSInteger height = tableView.bounds.size.height;
        height -= tableView.tableHeaderView.bounds.size.height;
        UIEdgeInsets insets = [self contextScrollViewContentInset];
        height -= insets.top;
        height -= insets.bottom;
        
        if (_refreshLoading)
        {
            if (![self supportPullRefreshHeader])
            {
                return height;
            }
            else
            {
                return 0;
            }
        }
        else if (!_refreshLoading)
        {
            //当没有数据 并且tableheaderview.height > table height  的时候 会得到一个负数的高度  导致crash
            if (height < 0){
                height = _emptyCellHeight;
            }
            return _emptyCellHeight > 0 ? _emptyCellHeight : height;
        }
        
    }
    else if (count > 0
             && [self supportGetMoreFooter]
             && indexPath.section == [tableView numberOfSections]-1
             && indexPath.row == [tableView.dataSource tableView:tableView numberOfRowsInSection:indexPath.section]-1)
    {
        if ([self hasMoreData]) {
            return Table_More_Cell_Height;
        } else {
            CGFloat noMoreDataHeight = [self model2UITableView_heightForNoMoreDataCell:self.tableView];
            if ((int)noMoreDataHeight > 0)
            {
                return noMoreDataHeight;
            }
        }
    }
    
    return [self model2UITableView:tableView heightForRowAtIndexPath:indexPath];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //重新加载，查看更多 公共处理
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    DLog(@"cell>> %@", cell);
    if (cell == _getMoreCell)
    {
        [self requestGetMore];
        return;
    }
    else if (cell == _emptyCell)
    {
        DLog(@"emptyCell clicked");
        if(_emptyCellReceiveClick){
            if (self.emptyCellClickBlock){
                self.emptyCellClickBlock();
            }
            [self triggerRefresh];
        }
        return;
    }
    
    if ([self.delegate respondsToSelector:@selector(adapter:tableView:didSelectRowAtIndexPath:)])
    {
        BOOL dealed = [self.delegate adapter:self tableView:tableView didSelectRowAtIndexPath:indexPath];
        if (dealed)
        {
            return;
        }
    }
    
    // 具体业务处理
    if ([self model2UITableView:tableView didSelectRowAtIndexPath:indexPath])
    {
        return;
    }
    else
    {
        //业务公共处理
    }
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (![cell isKindOfClass:[TGMTableEmptyCell class]] && ![cell isKindOfClass:[TGMTableMoreCell class]]){
        [self model2UITableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];
    }
    
/*  滑动效果
    NSArray *indexs = tableView.indexPathsForVisibleRows;
    
    CGRect frame = cell.frame;
    CGRect newFrame = frame;
    CGFloat h = ABS(tableView.velocityY) * 80;
    h = MIN(h, cell.boundsHeight);

    if (indexs.count && [indexPath compare:indexs.lastObject] != NSOrderedAscending)
    {
        newFrame.origin.y += h;
    }
    else if (indexs.count && [indexPath compare:indexs[0]] != NSOrderedDescending)
    {
        newFrame.origin.y -= h;
    }
    cell.frame = newFrame;
    CFTimeInterval time = MAX(h / 300 , 0.3);
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:time];
    cell.frame = frame;
    [UIView commitAnimations];
*/
}
/*
    为了业务 将此处的[self.listData count] 判断去掉
    只要子类实现了这个方法 就必须在调用之前判断 int count = [self.listData count] ＝＝ 0;
    进行风险预防
 */
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//    int count = [self.listData count];
//    if (count == 0)
//    {
//        return nil;
//    }
    return [self model2UITableView:tableView viewForHeaderInSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
//    int count = [self.listData count];
//    if (count == 0)
//    {
//        return 0.001;
//    }
    return [self model2UITableView:tableView heightForHeaderInSection:section];
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
//    int count = [self.listData count];
//    if (count == 0)
//    {
//        return nil;
//    }
    return [self model2UITableView:tableView viewForFooterInSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
//    int count = [self.listData count];
//    if (count == 0)
//    {
//        return 0.001;
//    }
    return [self model2UITableView:tableView heightForFooterInSection:section];
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    return [self model2UITableView:tableView canEditRowAtIndexPath:indexPath];
}


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    [self model2UITableView:tableView commitEditingStyle:editingStyle forRowAtIndexPath:indexPath];
}

-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    if (![cell isKindOfClass:[TGMTableEmptyCell class]] && ![cell isKindOfClass:[TGMTableMoreCell class]]){
    [self model2UITableView:tableView didEndDisplayingCell:cell forRowAtIndexPath:indexPath];
    }
}

- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    return [self model2SectionIndexTitlesForTableView:tableView];
}


- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
    return [self model2TableView:tableView sectionForSectionIndexTitle:title atIndex:index];
}

#pragma mark - Transfer to UITableViewDataSource & UITableViewDelegate

- (NSInteger)model2TableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{
    return index;
}

- (NSArray<NSString *> *)model2SectionIndexTitlesForTableView:(UITableView *)tableView{
    return nil;
}

- (void)model2UITableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
    
}

- (void)model2UITableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    
}

- (BOOL)model2UITableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    return NO;
}

- (NSInteger)model2UITableView_numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)model2UITableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.listData count];
}

- (UITableViewCell *)model2UITableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    return nil;
}

- (CGFloat)model2UITableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    return 0;
}

- (BOOL)model2UITableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    return NO;
}

- (void)model2UITableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    
}

- (UIView *)model2UITableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    return nil;
}

- (CGFloat)model2UITableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 0;
}

- (UIView *)model2UITableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    return nil;
}

- (CGFloat)model2UITableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0;
}

- (CGFloat)model2UITableView_heightForNoMoreDataCell:(UITableView *)tableView
{
    return 0;
}

#pragma mark - Transfer to UIScrollViewDelegate

- (void)model2TableViewDidScroll:(UIScrollView*)scrollView;
{
    
}
- (void)model2TableViewWillBeginDragging:(UIScrollView *)scrollView;
{
    
}
- (void)model2TableViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    
}
- (void)model2TableViewWillBeginDecelerating:(UIScrollView *)scrollView;
{
    
}
- (void)model2TableViewDidEndDecelerating:(UIScrollView *)scrollView;
{
    
}
- (void)model2TableViewDidEndScrollingAnimation:(UIScrollView *)scrollView;
{
    
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
{
    // @override
    [super scrollViewDidScroll:scrollView];
    
    [self model2TableViewDidScroll:scrollView];
}

// called on start of dragging (may require some time and or distance to move)
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
{
    [self model2TableViewWillBeginDragging:scrollView];
}

// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    [self model2TableViewDidEndDragging:scrollView willDecelerate:decelerate];
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;   // called on finger up as we are moving
{
    [self model2TableViewWillBeginDecelerating:scrollView];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;      // called when scroll view grinds to a halt
{
    // @override
    [super scrollViewDidEndDecelerating:scrollView];
    
    if ([self supportGetMoreFooter] && [self hasMoreData] && [_getMoreCell superview])
    {
        CGRect rc = _getMoreCell.frame;
        if(scrollView.contentOffset.y + scrollView.frame.size.height - rc.origin.y
           > (rc.size.height * 0.8))
        {
            [self performSelector:@selector(requestGetMore) withObject:nil afterDelay:0.0f];
        }
    }
    
    [self model2TableViewDidEndDecelerating:scrollView];
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView;
{
    [self model2TableViewDidEndScrollingAnimation:scrollView];
}

- (UIEdgeInsets)contextScrollViewContentInset
{
    if ([self.delegate respondsToSelector:@selector(adapter:tableViewLayoutContentInset:)])
    {
        return [self.delegate adapter:self tableViewLayoutContentInset:_tableView];
    }
    else
    {
        return UIEdgeInsetsMake(self.contextViewController.topLayoutGuide.length,
                                0,
                                self.contextViewController.bottomLayoutGuide.length,
                                0);
    }
}

#pragma mark - TGMTableEmptyCellDelegate

-(void)emptyCellDidClickActionBtnWithUrl:(NSString *)url{
    if (self.delegate && [self.delegate respondsToSelector:@selector(adapter:emptyCellClickWithUrl:)]){
        [self.delegate adapter:self emptyCellClickWithUrl:url];
    }
}

@end
